/*
 * dispatcher.h
 *
 *  Created on: Dec 19, 2013
 *      Author: elazar
 */

#ifndef DISPATCHER_H_
#define DISPATCHER_H_

/******************************************************************************
 * This abstract module gets a command line from the input stream and translates
 * it into the operation the application should implement.
 *
 *
 ******************************************************************************/
#include <string>
#include <iterator>
#include <sstream>
#include <list>
//#include <tuple>

#include <map>
#include <set>

using std::list;
using std::string;

enum Error { Error_SUCCESS,
	Error_UNKNOWN_COMMAND, Error_BAD_ARGS,
	Error_FILE_EXISTS, Error_FILE_DOES_NOT_EXIST, Error_FILE_LOCKED,
	Error_NOT_AN_OWNER, Error_ALREADY_OWNER,
	Error_ALREADY_CHECKED_OUT, Error_NOT_CHECKED_OUT, Error_NO_SUCH_VERSION
};

struct IllegalAction {
	string what;
	enum Error error;
	IllegalAction(Error e, string s="") : what(s),  error(e) {
	}

};

#define Map std::map
#define Set std::set

class Dispatcher {
	string post_usage;
	void run_command(string);
public:
	Dispatcher(string post_usage="") : post_usage(post_usage) {

	}

	typedef void cmd_func(Map<string, string> args);

	virtual cmd_func add_file = 0;
	virtual cmd_func checkout = 0;
	virtual cmd_func checkin = 0;
	virtual cmd_func get = 0;
	virtual cmd_func view_files = 0;
	virtual cmd_func view_versions = 0;
	virtual cmd_func update_owner = 0;
	virtual cmd_func undo_checkout = 0;
	virtual cmd_func view_my_co = 0;
	virtual cmd_func quit = 0;

	virtual string readline() = 0;

	virtual void handle(Error error) = 0;

	void run() {
		while (1) {
			try {
				run_command(readline());
			} catch (const IllegalAction& ac) {
				handle(ac.error);
			}
		}
	}

	virtual ~Dispatcher() {

	}

};

void print_map(Map<string, string> map);

#endif /* DISPATCHER_H_ */
